package main

import (
	"fmt"
	"go-demo-2025/demo/common"
	"math/rand"
	"sync"
	"time"
)

func init() {
	// 使用当前时间的纳秒数作为种子，确保每次运行程序的随机序列都不同
	rand.Seed(time.Now().UnixNano())
}

// Product 代表一个商品
type Product struct {
	ID    int
	Name  string
	Price float64
}

// ProductStore 是一个线程安全的商品存储
type ProductStore struct {
	rwmu     sync.RWMutex
	products map[int]Product
}

func NewProductStore() *ProductStore {
	return &ProductStore{
		products: make(map[int]Product),
	}
}

// CreateProduct 创建商品 (写操作)
func (ps *ProductStore) CreateProduct(p Product) {
	ps.rwmu.Lock()
	defer ps.rwmu.Unlock()
	time.Sleep(10 * time.Millisecond) // 模拟数据库延迟
	ps.products[p.ID] = p
	fmt.Printf("[CREATE] 商品 '%s' (ID: %d) 已上架。\n", p.Name, p.ID)
}

// UpdateProduct 修改商品价格 (写操作)
func (ps *ProductStore) UpdateProduct(id int, newPrice float64) bool {
	ps.rwmu.Lock()
	defer ps.rwmu.Unlock()
	time.Sleep(10 * time.Millisecond) // 模拟数据库延迟

	p, exists := ps.products[id]
	if !exists {
		fmt.Printf("[UPDATE] 商品 ID: %d 不存在，更新失败。\n", id)
		return false
	}

	p.Price = newPrice
	ps.products[id] = p
	fmt.Printf("[UPDATE] 商品 %s (ID: %d) 价格已更新为: %.2f。\n", p.Name, id, newPrice)
	return true
}

// DeleteProduct 删除商品 (写操作)
func (ps *ProductStore) DeleteProduct(id int) bool {
	ps.rwmu.Lock()
	defer ps.rwmu.Unlock()
	time.Sleep(10 * time.Millisecond) // 模拟数据库延迟

	if _, exists := ps.products[id]; !exists {
		fmt.Printf("[DELETE] 商品 ID: %d 不存在，删除失败。\n", id)
		return false
	}

	delete(ps.products, id)
	fmt.Printf("[DELETE] 商品 ID: %d 已下架。\n", id)
	return true
}

// GetProduct 查询单个商品 (读操作)
func (ps *ProductStore) GetProduct(id int) (Product, bool) {
	ps.rwmu.RLock()
	defer ps.rwmu.RUnlock()
	time.Sleep(5 * time.Millisecond) // 模拟数据库延迟

	p, exists := ps.products[id]
	if exists {
		fmt.Printf("[QUERY] 用户查询到商品: %s (ID: %d), 价格: %.2f。\n", p.Name, p.ID, p.Price)
	} else {
		fmt.Printf("[QUERY] 用户查询商品 ID: %d 不存在。\n", id)
	}
	return p, exists
}

func main() {
	store := NewProductStore()
	var wg sync.WaitGroup

	// 1. 初始创建几个商品
	fmt.Println("--- 阶段 1: 初始化商品 ---")
	initialProducts := []Product{
		{ID: 1, Name: "iPhone17", Price: 7999.0},
		{ID: 2, Name: "苹果原装充电器", Price: 825.88},
	}
	for _, p := range initialProducts {
		wg.Add(1)
		go func(product Product) {
			defer wg.Done()
			store.CreateProduct(product)
		}(p)
	}
	wg.Wait()

	// 2. 模拟并发操作：查询、更新、删除
	fmt.Println("\n--- 阶段 2: 并发操作 ---")
	// 模拟多个用户并发查询
	for i := 0; i < 5; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			store.GetProduct(common.GenerateRandomNumber(1, 2)) // 随机查询商品
		}()
	}

	// 后台管理员更新商品价格
	wg.Add(1)
	go func() {
		defer wg.Done()
		time.Sleep(100 * time.Millisecond) // 稍微延迟，确保有查询在进行
		store.UpdateProduct(1, 6999.0)     // 给 iPhone17 降价
	}()

	// 另一个管理员删除商品
	wg.Add(1)
	go func() {
		defer wg.Done()
		time.Sleep(200 * time.Millisecond) // 再延迟一些
		store.DeleteProduct(2)             // 删除商品 苹果原装充电器
	}()

	// 更新和删除后，再进行一些查询，验证结果
	wg.Add(2)
	go func() {
		defer wg.Done()
		time.Sleep(300 * time.Millisecond)
		store.GetProduct(1) // 应该能查到更新后的价格
	}()
	go func() {
		defer wg.Done()
		time.Sleep(300 * time.Millisecond)
		store.GetProduct(2) // 应该查询不到，因为已被删除
	}()

	wg.Wait()
}
